import socket from '@/utils/socket.js';
import media from './component/media.js';
export default {
    name: 'webRtc',
    components: {
        // setting
    },
    data() {
        return {
            account: window.sessionStorage.account || '',
            isJoin: !false,
            userList: [],
            roomid: 'webrtc_1v1', // 指定房间ID
            isCall: false, // 正在通话的对象
            loading: false,
            loadingText: '呼叫中',
            isToPeer: false, // 是否建立了 P2P 连接
            peer: null,
            offerOption: {
                offerToReceiveAudio: 1,
                offerToReceiveVideo: 1
            },
            //下面是我新加的
            isMedia: false, // 是否建立了 P2P 连接
            longstream: null,
            user: {},
            search: '',
            text: '',
            target: null, //聊天目标
            pageChat: [], //聊天框
            videobig: 'rtcA', //rtcB
            DisplayLocalstream: null,
            UserLocalstream: null,
            chatType: 'round',
            mediaType: 'getUserMedia', // getDisplayMedia | getUserMedia
            dialogVisible: false,
            isShowTextarea: false,
            activityId: "e6515e7499284bbb86925bc926bad1ed",
            activityType: 'attendance',
            keyword: '',
            command: 'a',
            managerList: [],
            memberList: [],
            media: null,
            file_video_list: [],
            file_audio_list: [],
            outputResolutionList:[//输出分辨率
            {label:'1920*1080 20fps',id:[1920,1080,20]},
            {label:'1600*900 20fps',id:[1600,900,20]},
            {label:'1366*768 30fps',id:[1366,768,30]},
            {label:'1280*768 30fps',id:[1280,768,30]},
            {label:'1280*720 30fps',id:[1280,720,30]},
            {label:'1024*576 30fps',id:[1024,576,30]},
            {label:'800*480 30fps',id:[800,480,30]},
            {label:'720*480 30fps',id:[720,480,30]},
            ],
            outputResolution:[1280,768,30],
        };
    },
    mounted() {
        this.isUserMedia = location.origin.includes('https://') || location.origin.includes('http://localhost')
        // this.init()
        this.initSocket();
        if (this.account) {
            this.join();
            console.log('登录....')
        }
        // this.getManagerList()
        // this.gitMemberList()
        // this.getUserMedia()
        // this.getDisplayMedia()
        this.media = new media()
    },
    methods: {
        change_file_video() {
            let file_video = document.getElementById("file_video")
            console.log(file_video)
            this.file_video_list.push(...file_video.files)
            file_video.value=null
        },
        updateSize(nBytes) {
            let sOutput = "0";
            // optional code for multiples approximation
            for (let aMultiples = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"], nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
                sOutput = nApprox.toFixed(3) + aMultiples[nMultiple];
            }
            return sOutput
        },
        change_file_audio() {
          let  file_audio = document.getElementById("file_audio")
          this.file_audio_list.push(...file_audio.files)
          file_audio.value=null
        },
        // 管理员列表
        getManagerList() {
            this.services.live.managerList({ keyword: this.keyword, activityId: this.activityId }).then((res) => {
                this.managerList.push(...res.data.managers)
                console.log(this.managerList)
            }, (err) => {
                this.$eleEx.alert({ msg: err.msg }, this)
            })
        },
        // 成员列表
        gitMemberList() {
            this.services.live.memberList({ keyword: this.keyword, activityId: this.activityId }).then((res) => {
                this.memberList.push(...res.data.memberList)
                console.log(this.memberList)

            }, (err) => {
                this.$eleEx.alert({ msg: err.msg }, this)
            })
        },
        async handleCommand(command) {
            this.command = command
            this.media.stopUserMedia()
            this.media.stopDisplayMedia()
            let stream
            if (command == 'a') {
                stream = await this.media.getUserMedia()
            }
            if (command == 'b') {
                stream = await this.media.getUserMedia({ video: false, audio: true })
            }
            if (command == 'c') {
                stream = await this.media.getDisplayMedia()
            }
            let video = document.querySelector('#rtcA');
            video.srcObject = stream
        },
        _join() {
            console.log(this.account)
            this.isJoin = true
        },
        goto() {
            this.$router.push({
                path: '/PCoverview',
                query: {

                }
            })
        },
        setChatType(type) {
            this.chatType = type
        },
        setMedia() {
            this.dialogVisible = false
            if (this.mediaType == 'getUserMedia') {
                this.getUserMedia()
            } else {
                this.getDisplayMedia()
            }
        },
        // 分享屏幕
        async getDisplayMedia() {
            const gdmOptions = {
                video: {
                    cursor: "always"
                },
                audio: false,
                /*              audio: {
                  echoCancellation: true,
                  noiseSuppression: true,
                  sampleRate: 44100
                }*/
            }
            // this.stopStream()
            // 保存本地流到全局
            try {
                this.DisplayLocalstream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: { mediaSource: 'screen' } });
                let video = document.querySelector('#rtcA');
                if (video.srcObject) {
                    video.srcObject.getTracks().forEach(track => {
                        track.stop();
                    });
                }
                video.srcObject = this.DisplayLocalstream;
                this.isMedia = true
                // console.log('this.DisplayLocalstream.getVideoTracks():',this.DisplayLocalstream.getVideoTracks())
                // console.log('this.DisplayLocalstream.getAudioTracks():',this.DisplayLocalstream.getAudioTracks())
                console.log('this.DisplayLocalstream.getTracks():', this.DisplayLocalstream.getTracks())
                this.localstream = this.DisplayLocalstream;
            } catch (e) {
                console.log('getDisplayMedia: ', e)
            }
        },
        // 分享摄像头和麦克风
        async getUserMedia() {
            // this.stopStream()
            // 保存本地流到全局
            try {
                this.UserLocalstream = await navigator.mediaDevices.getUserMedia({
                    audio: {
                        echoCancellation: true, //是否使用回声消除来尝试去除通过麦克风回传到扬声器的音频
                        channelCount: 2, //单声道的时候为1，立体声的时候为2
                        noiseSuppression: true, //是否尝试去除音频信号中的背景噪声
                    },
                    video: {
                        aspectRatio: {
                            ideal: 1.777777 // 16:9比例优先
                        },
                        /*               mandatory: {
                                               maxHeight: 180,
                                               maxWidth: 320
                                           }*/
                    }
                });
                let video = document.querySelector('#rtcA');
                if (video.srcObject) {
                    video.srcObject.getTracks().forEach(track => {
                        track.stop();
                    });
                }
                video.srcObject = this.UserLocalstream;
                this.isMedia = true
                // console.log('this.UserLocalstream.getVideoTracks():',this.UserLocalstream.getVideoTracks())
                // console.log('this.UserLocalstream.getAudioTracks():',this.UserLocalstream.getAudioTracks())
                // console.log('this.UserLocalstream.getTracks():',this.UserLocalstream.getTracks())
                this.localstream = this.UserLocalstream;
            } catch (e) {
                console.log('getUserMedia: ', e)
            }
        },

        stopStream() {
            if (this.localstream) {
                this.localstream.getTracks().forEach(track => {
                    track.stop();
                });
                this.localstream = null
            }
        },
        // 登录相关开始
        /*
           房间ID roomid 为 活动 activityId 
           登录名 account 为 userId
           window.sessionStorage 用于临时保存同一窗口(或标签页)的数据，刷新还在保存 在关闭窗口或标签页之后将会删除这些数据。
        */
        join() {
            if (!this.account) return;
            this.isJoin = true;
            window.sessionStorage.account = this.account;
            socket.emit('join', { roomid: this.roomid, account: this.account, isUserMedia: this.isUserMedia });
        },
        // 登录相关结束
        onMessage(data) {
            console.log('onMessage', data)
            if (data.type == 'text') {
                this.acceptText(data)
            } else {
                console.log(data)
            }
        },
        // 文字聊天开始
        // 接收
        acceptText(data) {
            this.pageChat.push(data)
        },
        showFile() {
            var file = document.querySelector('input[type="file"]')
                .files[0];
            console.log(file)
        },
        binary() {
            // socket.binary(false).emit('an event', { some: 'data' });// 发送二进制 数据  指定发出的数据是否包含二进制。指定时提高性能。可以是true或false。
            var file = document.querySelector('input[type="file"]')
                .files[0];
            console.log(file)
            let data = {
                roomid: this.roomid,
                self: this.account,
                type: 'Blob',
                data: file,
                fileName: file.name,
                fileSize: file.size,
                fileType: file.type,
                date: new Date().toLocaleString()
            }
            socket.emit('offer', data)

        },
        // 发送
        sendText() {
            if (!this.text) return
            let data = { roomid: this.roomid, self: this.account, type: 'text', text: this.text, date: new Date().toLocaleString() }
            socket.emit('offer', data)

            this.pageChat.push(data)
            this.text = ''
        },
        // 文字聊天结束

        // 纯语音聊天开始
        // 纯语音聊天结束

        // 视频语音聊天开始
        myapply() {
            if (!this.target) return
            this.apply(this.target.account)
        },
        // 视频语音聊天结束

        // socket 连接相关 开始
        // socket 连接相关 结束

        // RTCPeerConnection 相关开始
        // RTCPeerConnection 相关结束

        // video 流相关 开始
        // video 流相关 结束

        initSocket() {
            socket.on('joined', (data) => { // 收到登录
                this.userList = data;
                console.log(data)
            });
            socket.on('reply', async data => { // 收到回复
                this.loading = false;
                console.log(data);
                switch (data.type) {
                    case '1': // 同意
                        this.isCall = data.self;
                        // 对方同意之后创建自己的 peer
                        await this.createP2P(data);
                        // 并给对方发送 offer
                        this.createOffer(data);
                        break;
                    case '2': //拒绝
                        this.$message({
                            message: '对方拒绝了你的请求！',
                            type: 'warning'
                        });
                        break;
                    case '3': // 正在通话中
                        this.$message({
                            message: '对方正在通话中！',
                            type: 'warning'
                        });
                        break;
                    case '4': // 发送文字
                        this.acceptText(data)
                        break;
                    default:
                        console.error('收到没有匹配的回复！')
                }
            });
            socket.on('apply', data => { // 收到请求
                if (this.isCall) {
                    this.reply(data.self, '3');
                    return;
                }
                this.$confirm(data.self + ' 向你请求视频通话, 是否同意?', '提示', {
                    confirmButtonText: '同意',
                    cancelButtonText: '拒绝',
                    type: 'warning'
                }).then(async () => {
                    await this.createP2P(data); // 同意之后创建自己的 peer 等待对方的 offer
                    this.isCall = data.self;
                    this.reply(data.self, '1');
                }).catch(() => {
                    this.reply(data.self, '2');
                });
            });
            socket.on('1v1answer', (data) => { // 接收到 answer
                this.onAnswer(data);
            });
            socket.on('1v1ICE', (data) => { // 接收到 ICE
                this.onIce(data);
            });
            socket.on('1v1offer', (data) => { // 接收到 offer
                this.onOffer(data);
            });
            socket.on('1v1hangup', _ => { // 通话挂断
                this.$message({
                    message: '对方已断开连接！',
                    type: 'warning'
                });
                this.peer.close();
                this.peer = null;
                this.isToPeer = false;
                this.isCall = false;
                this.localstream.getTracks().forEach(track => {
                    track.stop();
                });
            });
            socket.on('offer', (data) => { // 接收到 message
                console.log('socket.on', data)
                this.onMessage(data);
            });
        },
        hangup() { // 挂断通话
            socket.emit('1v1hangup', { account: this.isCall, self: this.account });
            this.peer.close();
            this.peer = null;
            this.isToPeer = false;
            this.isCall = false;
            this.localstream.getTracks().forEach(track => {
                track.stop();
            });
        },
        apply(account) {
            // account 对方account  self 是自己的account
            this.loading = true;
            this.loadingText = '呼叫中';
            socket.emit('apply', { account: account, self: this.account });
        },
        reply(account, type) {
            socket.emit('reply', { account: account, self: this.account, type: type });
        },
        async createP2P(data) {
            // this.loading = true;
            // this.loadingText = '正在建立通话连接';
            await this.createMedia(data);
        },
        async createMedia(data) {
            const constraints = {
                width: { min: 640, ideal: 1280 },
                height: { min: 480, ideal: 720 },
                advanced: [
                    { width: 1920, height: 1280 },
                    { aspectRatio: 1.333 }
                ]
            };
            // 保存本地流到全局
            if (!this.localstream) {
                try {
                    this.localstream = await navigator.mediaDevices.getUserMedia(constraints);
                    // this.localstream = await navigator.mediaDevices.getDisplayMedia({video: {mediaSource: 'screen'}});
                    // const trackgetVideoTracks = this.localstream.getVideoTracks()[0];
                    // const trackgetAudioTracks = this.localstream.getAudioTracks() ;// 获取 Audio 流 数组
                    // const trackgetTracks = this.localstream.getTracks() ;// 获取 所有 流 数组
                    // track.applyConstraints(constraints) // 添中约束
                    let video = document.querySelector('#rtcA');
                    video.srcObject = this.localstream;
                } catch (e) {
                    console.log('getUserMedia: ', e)
                }

            }
            this.initPeer(data); // 获取到媒体流后，调用函数初始化 RTCPeerConnection
        },
        initPeer(data) {
            // 创建输出端 PeerConnection
            let PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
            this.peer = new PeerConnection();
            this.peer.addStream(this.localstream); // 添加本地流
            // 监听ICE候选信息 如果收集到，就发送给对方
            this.peer.onicecandidate = (event) => {
                if (event.candidate) {
                    socket.emit('1v1ICE', { account: data.self, self: this.account, sdp: event.candidate });
                }
            };
            this.peer.onaddstream = (event) => { // 监听是否有媒体流接入，如果有就赋值给 rtcB 的 src
                this.isToPeer = true;
                this.loading = false;
                let video = document.querySelector('#rtcB');
                video.srcObject = event.stream;
            };
            this.peer.oniceconnectionstatechange = (event) => { //。当连接的ICE代理的状态（以该iceConnectionState属性表示）改变时，会触发。
                /*              if (this.peer.iceConnectionState === "failed" ||
                                  this.peer.iceConnectionState === "disconnected" ||
                                  this.peer.iceConnectionState === "closed") {
                                // Handle the failure
                              }*/
                // console.log(event)
            };
            this.peer.onicegatheringstatechange = ev => { //当ICE候选者收集过程的状态发生变化时
                let connection = ev.target;
                console.log(connection)

                // switch(connection.iceGatheringState) {
                //   case "gathering":
                //     /* collection of candidates has begun */
                //     break;
                //   case "complete":
                //     /* collection of candidates is finished */
                //     break;
                // }
            }
            this.peer.onopen = ev => {
                console.log('this.peer.onopen 打开')
            }
        },
        async createOffer(data) { // 创建并发送 offer
            try {
                // 创建offer
                let offer = await this.peer.createOffer(this.offerOption);
                // 呼叫端设置本地 offer 描述
                await this.peer.setLocalDescription(offer);
                // 给对方发送 offer
                socket.emit('1v1offer', { account: data.self, self: this.account, sdp: offer });
            } catch (e) {
                console.log('createOffer: ', e);
            }
        },
        async onOffer(data) { // 接收offer并发送 answer
            try {
                // 接收端设置远程 offer 描述
                await this.peer.setRemoteDescription(data.sdp);
                // 接收端创建 answer
                let answer = await this.peer.createAnswer();
                // 接收端设置本地 answer 描述
                await this.peer.setLocalDescription(answer);
                // 给对方发送 answer
                socket.emit('1v1answer', { account: data.self, self: this.account, sdp: answer });
            } catch (e) {
                console.log('onOffer: ', e);
            }
        },
        async onAnswer(data) { // 接收answer
            try {
                await this.peer.setRemoteDescription(data.sdp); // 呼叫端设置远程 answer 描述
            } catch (e) {
                console.log('onAnswer: ', e);
            }
        },
        async onIce(data) { // 接收 ICE 候选
            try {
                await this.peer.addIceCandidate(data.sdp); // 设置远程 ICE
            } catch (e) {
                console.log('onAnswer: ', e);
            }
        },

        dragEagle(e) {
            var targetDiv = document.getElementById('eagleMapContainer'); //e.target.parentNode.parentNode;.children[0]

            //得到点击时该地图容器的宽高：
            var targetDivWidth = targetDiv.offsetWidth;
            var targetDivHeight = targetDiv.offsetHeight;

            var startX = e.clientX;
            var startY = e.clientY;

            var _this = this;

            document.onmousemove = function(e) {
                console.log('move');
                e.preventDefault();
                //得到鼠标拖动的宽高距离：取绝对值
                var distX = Math.abs(e.clientX - startX);
                var distY = Math.abs(e.clientY - startY);

                //往右上方拖动：
                if (e.clientX > startX) {
                    targetDiv.style.width = targetDivWidth + distX + 'px';
                    // targetDiv.style.height=targetDivHeight+distY+'px';
                }
                //往左下方拖动：
                if (e.clientX < startX) {
                    targetDiv.style.width = (targetDivWidth - distX) + 'px';
                    // targetDiv.style.height=(targetDivHeight-distY)+'px';
                }

                //设置最大最小范围：不能无限制缩放，影响体验
                if (parseInt(targetDiv.style.width) >= 1300) {
                    targetDiv.style.width = 1300 + 'px';
                }
                if (parseInt(targetDiv.style.width) <= 150) {
                    targetDiv.style.width = 150 + 'px';
                }

                /*                if(parseInt(targetDiv.style.height)>=300){
                                    targetDiv.style.height=300+'px';
                                }
                                if(parseInt(targetDiv.style.height)<=150){
                                    targetDiv.style.height=150+'px';
                                }*/
            }

            document.onmouseup = function() {
                document.onmousemove = null;
            }
        },
        info() {
            this.$message({
                message: '开发中！',
                type: 'warning'
            });
        },
        init() {
            if ('getUserMedia' in navigator.mediaDevices) {
                // 请用摄像头                
                this.getUserMedia()
            } else
            if ('getDisplayMedia' in navigator.mediaDevices) {
                // use it.
                console.log("支持 getDisplayMedia()");
            } else {
                console.log("不支持 getDisplayMedia()");
                // fall back to extension way
            }
        },

    }

}